from Products.Five import BrowserView
from zope.component import getMultiAdapter
from zope.interface import implements
from Acquisition import aq_inner, aq_base, aq_parent
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.i18nl10n import ulocalized_time
from plone.app.layout.globals.interfaces import IViewView
from plone.memoize import ram
from plone.memoize.view import memoize
from plone.app.layout.navigation.navtree import buildFolderTree
from plone.app.layout.navigation.navtree import NavtreeStrategyBase

import pyquery
from plonetheme.apkntheme import APKNThemeMessageFactory as _, logger
from plonetheme.apkntheme.settings import *
from plonetheme.apkntheme.browser.syndication import random_string,\
									getFeedItems as getRSSItems
from plonetheme.apkntheme.utils.tools import checkURLExists

from datetime import datetime
import re
from time import time
import logging

try:
	import json
except ImportError:
	import simplejson as json
	
pq = pyquery.PyQuery

def format_field(value):
	'''
	Format values as strings based on their type
	'''
	final_value = value
	if isinstance(value, list):
		final_value = ','.join(value)
	logging.debug("Finished formatting value %s of type %s. Final Value @@ %s", str(value), type(value), final_value)
	return final_value


def compute_request_cache_key(method, browser_view):
	'''
	Compute cache key for news feeds. Path info is prepended to ensure
	unique keys are generated
	'''
	timeDiff = time()//CACHE_SECONDS_DEFAULT
	path_info = browser_view.request.environ.get('PATH_INFO')
	key = "%s:%s" %(str(timeDiff), path_info)
	logger.debug("DASHBOARD: computed cache key @@ %s", key)
	return key

def compute_cache_key_rss_parliaments(method, browser_view):
	'''
	Compute a cache key for the parliamentary news feed. 
	This is only required once.
	'''
	timeDiff = time()//CACHE_SECONDS_DEFAULT
	key = "%s:%s" %(str(timeDiff), CACHE_RSS_KEY_PARLIAMENTS)


class translatePanel(BrowserView):
	"""
	Renders Macro Containing Translation Machinery
	"""

class SearchContactDirectories(BrowserView):
	
	def searchResults(self, show_all = False):
		if self.searchSubmitted() and not show_all:
			search_text = self.getSearchParam(SEARCH_TEXT_PARAM)
			search_path = self.getSearchParam(SEARCH_PATH_PARAM)
			results = self.performSearch(search_text, search_path)
		else:
			results = self.performSearch()
		final_results = []
		for result in results:
			path = result.getPath()
			country = path.rsplit('/country-folders/')\
			[1].split('/')[0]
			country_caps = country.capitalize()
			
			country_path = COUNTRY_FOLDERS_PATH + country
			country_code = ''
			try:
				country_object = self.context.restrictedTraverse(country_path)
				if country_object:
					country_code = getattr(country_object, COUNTRY_FOLDER_META, '')
			except:
				pass
			url = result.getURL()
			title = result.Title
			final_results.append({'link': url,
			'country': country_caps,
			'title': title,
			'country_code': country_code.upper()
			})
		sorted_final_results = sorted(final_results, 
		key = lambda v: v['country'])
		
		result_count = len(sorted_final_results)
		search_message = self.getSearchMessage(result_count)
		
		search_data = {'search_results': sorted_final_results, 
		'search_message': search_message}
		return search_data
	
	def getDataForMap(self):
		search_results = self.searchResultsAll()
		#uniqify
		all_codes = [s['country_code'] for s in search_results]
		st = {}
		map(st.__setitem__, all_codes, [])
		unique_codes = st.keys()
		
		final_codes = [{'country_code': code,'links': [] } \
		for code in unique_codes]
		
		code_data = {}
		for res in search_results:
			c_code = res['country_code']
			if code_data.has_key(c_code):
				link_data = (res['link'], res['title'])
				code_data[c_code]['links'].append(link_data)
			else:
				link_list = list()
				link_data = (res['link'], res['title'])
				link_list.append(link_data)
				code_data[c_code] = {'links': link_list,
				'country': res['country']}
		
		map_data = json.dumps(final_codes)
		code_data_json = json.dumps(code_data)
		return u'window[\'dataForMap\'] = ' + map_data +\
		'; window[\'codeDataForMap\'] = ' + code_data_json

	def getGeoCodes(self):
		query_path = {'query': COUNTRY_FOLDERS_PATH, 'depth': 2}
		catalog = getToolByName(self.context, u'portal_catalog')
		country_folders = catalog(path = query_path, 
		meta_type = (u'ATFolder'))
		country_folder_objects_raw = [c.getObject() for c in country_folders]
		country_folder_objects = filter(lambda s: hasattr(s, COUNTRY_FOLDER_META), 
		country_folder_objects_raw)
		obj_data = []
		try:
			obj_data = [
			{'title': c.title, 
			'lat': c.geo_latitude, 
			'lng': c.geo_longitude, 
			'code': getattr(c, COUNTRY_FOLDER_META).upper()} 
			for c in country_folder_objects]
		except:
			logger.info("Could not load GeoData - Country Folders not yet GeoCoded")
		json_geo = json.dumps(obj_data)
		return u'window[\'geoCodes\']=%s' % json_geo
	
	def searchResultsAll(self):
		return self.searchResults(True)['search_results']
	
	def performSearch(self, search_text = None, search_location = None):
		current_object = aq_inner(self.context)
		catalog = self.context.portal_catalog
		search_path = '/'.join(current_object.getPhysicalPath())
		search_types = CONTACT_SEARCH_PORTAL_TYPES
		type_filter = {'query': search_types, 'operator': 'or'}
		
		query = {}
		query['meta_type'] = type_filter
		query['path'] = search_path
		query['review_state'] = u'published'
		if search_text:
			query['SearchableText'] = search_text
		if search_location:
			search_path = '/'.join((search_path, search_location))
			query['path'] = search_path
		logger.info("Performing catalog query with params %s", 
		query.__str__())
		results = catalog.searchResults(query)
		return results
	
	def searchSubmitted(self):
		submitted = False
		submit_button = self.request.form.get(SEARCH_BUTTON_PARAM, 
											  False)
		if submit_button:
			submitted = True
		return submitted
	
	def getSearchParam(self, param_name):
		search_text = self.request.form.get(param_name, None)
		return search_text

	def getSearchMessage(self, result_count):
		country = self.getSearchParam(SEARCH_PATH_PARAM)
		if country:
			country = country.replace('-', ' ').title()
		else:
			country = _(u'all countries')
		search_text = self.getSearchParam(SEARCH_TEXT_PARAM)
		if not search_text:
			search_text = _(u'all directories')
		search_message = _(u'search_contacts_status_message',
		default = u'Your search for "${search_text}" in \
		"${country_folder}" yielded ${result_count} hits',
		mapping = {u'search_text': search_text, 
		u'country_folder': country,
		u'result_count': result_count}
		)
		return search_message 

	@ram.cache(compute_request_cache_key)
	def getCountryList(self):
		country_list = []
		context_object = aq_inner(self.context)
		object_ids = context_object.objectIds()
		selected_value = None
		if self.searchSubmitted():
			selected_value = self.getSearchParam(SEARCH_PATH_PARAM)
		for obj_id in object_ids:
			obj = None
			try:
				obj = getattr(context_object, obj_id)
			except:
				logger.error("Unable to extract info for object with id %s", obj_id)
			if obj:
				pre_selected_value = None
				if selected_value == obj_id:
					pre_selected_value = u'selected'
				if hasattr(obj, COUNTRY_FOLDER_META):
					country_list.append({'title': obj.Title(), 
					'id': obj_id, 'selected': pre_selected_value})
		return country_list

class countryFolderContainer(BrowserView):
	'''
	View for country folders container
	#TODO: memoize
	'''
	
	def  getContextMenu(self):
		pass
	
	@ram.cache(compute_cache_key_rss_parliaments)
	def getFeedItems(self):
		all_items = []
		for feed in ANM_PARLIAMENT_FEEDS:
			rss_url = ANM_PARL_FEED_URL %(feed['id'], 
			DEFAULT_FEED_LANGUAGE)
			items = {}
			items['title'] = feed['title']
			items['news_url'] = ANM_PARL_NEWS_URL %(DEFAULT_FEED_LANGUAGE,
			feed['id'])
			set_items = []
			try:
				feed_content = pq(rss_url)
				feed_items = pq('item', pq(feed_content))
				for item in feed_items:
					link = pq('link', pq(item))
					title = pq('title', pq(item))
					link_text = pq(link).text()
					title_text = pq(title).text()
					set_items.append({'title':title_text,'link': link_text})
					if len(set_items) > FEED_ITEMS_COUNT_ROOT:
						break
			except Exception, e:
				logger.error("Failed to load parliaments news feed %s.\
				 Error @@  %s", feed['id'], e.__str__())
			items['items'] = set_items
			items['has_items'] = bool(len(set_items))
			all_items.append(items)
		return all_items

	def getCountryListing(self):
		'''
		Return a list of country title and name from the
		in ../settings.py find COUNTRY_CONTEXT_MENU_ROOT
		'''
		container_object = aq_inner(self.context)
		listing = []
		filter_type = self.getRequestParam(PARAM_CONTENT_FILTER)
		filter_settings = COUNTRY_CONTEXT_MENU_ROOT[filter_type]
		
		obj_ids = container_object.objectIds()
		for obj_id in obj_ids:
			obj = None
			try:
				obj = getattr(container_object, obj_id)
				if not hasattr(obj, COUNTRY_FOLDER_META):
					obj = None
			except Exception, e:
				logger.error("Failed to load object from country folder \
				with id %s. Error @@ %s", obj_id, e.__str__())
			if obj:
				CONTEXT_ID = obj.getId()
				CONTEXT_TITLE = obj.Title()
				CONTEXT_URL = obj.absolute_url()
				listing.append({'link': CONTEXT_URL, 
				'title': CONTEXT_TITLE})
		return listing

	def getRequestParam(self, paramName):
		param = self.request.form.get(paramName,None)
		return param
		
	def validateParam(self, paramName, filterValues):
		param = self.getRequestParam(paramName)
		if param in filterValues:
			return param
		else:
			return None

	def isUserAnonymous(self):
		pm = getToolByName(self.context, 'portal_membership')
		anon = pm.isAnonymousUser()
		return anon

	def hasContentFilter(self):
		has_content_filter = True
		if self.validateParam(PARAM_CONTENT_FILTER, 
								ALLOWED_DASHBOARD_ACTIONS_ROOT) is None:
									has_content_filter = False
		return has_content_filter

	def getSiblingsOfType(self, meta_type, container, fields):
		item_list = []
		object_ids = container.objectIds()
		for oid in object_ids:
			obj = getattr(container, oid)
			if obj.meta_type in meta_type:
				title = obj.Title()
				link = obj.absolute_url()
				field_data = {}
				if fields:
					for field_name in fields:
						field_value = getattr(obj, field_name)
						field_value = format_field(field_value)
						field_data[field_name] = field_value
				item_list.append((title, link, field_data))
			if len(item_list) >= RECENT_ITEM_COUNT:
				break
		return item_list

	def searchResults(self, meta_type, fields = None):
		'''
		Search current context for objects of a particular type
		'''
		items = []
		current_object = aq_inner(self.context)
		current_path = '/'.join(current_object.getPhysicalPath())
		portal_catalog = getToolByName(self.context, 'portal_catalog')
		search_results = portal_catalog(
			meta_type =  meta_type,
			path = current_path,
			limit = RECENT_ITEM_COUNT,
			sort_on = 'Date',
			review_state = 'published'
		)
		if search_results:
			for result in search_results:
				field_data = {}
				if fields:
					obj = result.getObject()
					for field_name in fields:
						field_value = getattr(obj, field_name)
						final_value = format_field(field_value)
						field_data[field_name] = final_value
				itm = (result.Title, result.getURL(), field_data)
				items.append(itm)
		return items

	def getSiblingsFromLocation(self, meta_type, location, which, fields):
		item_list = []
		current_object = aq_inner(self.context)
		portal_url = getToolByName(self.context, 'portal_url')
		workflow_tool = getToolByName(self.context, 'portal_workflow')
		portal = portal_url.getPortalObject()
		try:
			real_location = eval(location)
		except:
			real_location = location
		container = portal.restrictedTraverse(real_location)
		if container:
			if which == ITEMS_RECENT:
				object_ids = container.objectIds()
				for obj_id in object_ids:
					obj = getattr(container, obj_id)
					publish_state = workflow_tool.getInfoFor(obj, \
					'review_state')
					if (publish_state == u'published')\
					and (obj.portal_type == meta_type):
						field_data = {}
						if fields:
							for field_name in fields:
								field_value = getattr(obj, field_name)
								field_value = format_field(field_value)
								field_data[field_name] = field_value
						item_list.append((obj.title, obj.absolute_url(),
						field_data))
					if len(item_list) >= RECENT_ITEM_COUNT_ROOT:
						break
		return item_list

	def  getRecentItems(self):
		""" 
		List the recent content in Main Country Page 
		Based on recent item filters and filter methods
		"""
		current_object = aq_inner(self.context)
		item_listing = []
		
		for filter_item in RECENT_ITEM_FILTERS_ROOT:
			this_list = dict()
			this_list['id'] = filter_item[0]
			this_list['title'] = filter_item[3]
			this_list['rend_id'] = filter_item[4]
			this_list['extra_fields'] = filter_item[5]
			this_list['section_header'] = filter_item[6]
			extra_fields = this_list['extra_fields']
			#get all items for current type
			method, ident = filter_item[2].split(':')
			meta_type = filter_item[1]
			if method == 'SKIP':
				this_list['items'] = []
			elif method == "HERE":
				this_list['items'] = \
				self.getSiblingsOfType(meta_type, current_object,
				extra_fields)
			elif method == 'LOOKUP':
				this_list['items'] = \
				self.getSiblingsFromLocation(meta_type, ident, ITEMS_RECENT,
				extra_fields)
			elif method == 'SEARCH':
				this_list['items'] = \
				self.searchResults(meta_type, extra_fields)
			else:
				this_list['items'] = []
			item_listing.append(this_list)
		return item_listing

class countryFolderMain(BrowserView):
	"""
	Country folder dynamic browser view
	Filters by content type or display dashboard
	of items
	#TODO memoize, add menus to interface
	"""
	implements(IViewView)
	
	def getRequestParam(self, paramName):
		param = self.request.form.get(paramName,None)
		return param
		
	def validateParam(self, paramName, filterValues):
		param = self.getRequestParam(paramName)
		if param in filterValues:
			return param
		else:
			return None

	def isUserAnonymous(self):
		pm = getToolByName(self.context, 'portal_membership')
		anon = pm.isAnonymousUser()
		return anon

	def getContextMenu(self):
		'''
		Gets the menu items for country folder content types with
		the option to get a link to a particular item and optional
		display based on user login status.
		See: COUNTRY_CONTEXT_MENU defined in ../settings.py
		'''
		current_object = aq_inner(self.context)
		CONTEXT_ID = current_object.id
		CONTEXT_TITLE = current_object.Title()
		CONTEXT_COUNTRY_CODE = current_object.get(COUNTRY_FOLDER_META,\
																	'')
		if CONTEXT_COUNTRY_CODE:
			CONTEXT_COUNTRY_CODE += '.'
		menu_items = []
		for cmenu in COUNTRY_CONTEXT_MENU:
			link = cmenu[1]
			link = link.replace(u'@@CONTEXT_ID', CONTEXT_ID)
			link = link.replace(u'@@CONTEXT_TITLE', CONTEXT_TITLE)
			link = link.replace(u'@@CONTEXT_COUNTRY_CODE', \
												CONTEXT_COUNTRY_CODE)
			
			if cmenu[2]:
				content_items = self.getSiblingsOfType(cmenu[2], 
				current_object)
				if len(content_items) == 1:
					link = content_items[0][1]
			
			show = cmenu[3]
			
			
			if cmenu[5]:
				exists = checkURLExists(link)
			else:
				exists = True
			if (not show) and (self.isUserAnonymous()):
				pass
			else:
				menu_items.append({'title': cmenu[0], 'link': link, 'exists': exists})
		return menu_items

	def hasContentFilter(self):
		has_content_filter = True
		if self.validateParam(PARAM_CONTENT_FILTER, 
								ALLOWED_DASHBOARD_ACTIONS) is None:
									has_content_filter = False
		return has_content_filter

	def listSiblings(self):
		current_object = aq_inner(self.context)
		this_country = current_object.title
		object_ids = current_object.objectIds()
		type_filter = self.getRequestParam(PARAM_CONTENT_FILTER)
		show_type = TYPE_FILTERS[type_filter]
		olist = []
		
		if show_type == u'Resource':
			resource_container = aq_parent(current_object)
			resource_folder = getattr(resource_container, 'resources-1')
			resource_ids = resource_folder.objectIds()
			
			for res_id in resource_ids:
				obj = getattr(resource_folder, res_id)
				if obj.portal_type == show_type:
					o_country = getattr(obj,'country')
					if str(this_country).lower() == str(o_country).lower():
						olist.append(obj)
		else:
			for oid in object_ids:
				obj = getattr(current_object, oid)
				if obj.portal_type == show_type:
					olist.append(obj)
		return olist
	
	def getPortalTypeStyle(self, obj):
		style=""
		type_icon = obj.getIcon()
		if type_icon:
			style = "background-image:url('/%s') no-repeat center center;" %(type_icon)
		return style
		
	def getCountryFlag(self):
		country_name = unicode(self.context.Title())
		lang_tool = getToolByName(self.context, u'portal_languages', None)
		countries = lang_tool.getAvailableCountries()
		this_country = filter(lambda x: x[u'name'] == country_name, countries.values())
		if this_country:
			return this_country[0][u'flag']
		else:
			return None

	def getRequest(self):
		return self.request.__dict__
		
	def getDashboardSectionTitle(self):
		type_filter = self.getRequestParam(PARAM_CONTENT_FILTER)
		context_title = SECTION_TITLES[type_filter]
		return context_title

	def getSiblingsOfType(self, meta_type, container, fields = None):
		item_list = []
		object_ids = container.objectIds()
		for oid in object_ids:
			obj = getattr(container, oid)
			if obj.portal_type in meta_type:
				title = obj.Title()
				link = obj.absolute_url()
				field_data = {}
				if fields:
					for field_name in fields:
						field_value = getattr(obj, field_name)
						field_value = format_field(field_value)
						field_data[field_name] = field_value
				item_list.append((title, link, field_data))
			if len(item_list) >= RECENT_ITEM_COUNT:
				break
		return item_list

	def searchResults(self):
		'''
		This does not fetch results as desired
		We use getSiblingsFromLocation instead
		'''
		current_object = aq_inner(self.context)
		results = self.context.portal_catalog(
			path = RESOURCES_PATH,
			country = current_object.title,
			limit = 20,
			sort_on = 'Date',
			review_state = 'published'
		)
		return results

	def getSiblingsFromLocation(self, meta_type, location, which, fields = None):
		item_list = []
		current_object = aq_inner(self.context)
		the_country = current_object.title
		portal_url = getToolByName(self.context, 'portal_url')
		portal = portal_url.getPortalObject()
		try:
			real_location = eval(location)
		except:
			real_location = location
		container = portal.restrictedTraverse(real_location)
		if container:
			if which == ITEMS_RECENT:
				object_ids = container.objectIds()
				for obj_id in object_ids:
					obj = getattr(container, obj_id)
					if obj.portal_type in meta_type:
						obj_country = getattr(obj, 'country')
						if obj_country.lower() == the_country.lower():
							field_data = {}
							if fields:
								for field_name in fields:
									field_value = getattr(obj, field_name)
									field_value = format_field(field_value)
									field_data[field_name] = field_value
							item_list.append((obj.title, 
							obj.absolute_url(), field_data))
					if len(item_list) >= RECENT_ITEM_COUNT:
						break
		return item_list

	def  getRecentItems(self):
		""" 
		List the recent content in Country Dashboard 
		Based on recent item filters and filter methods
		"""
		current_object = aq_inner(self.context)
		item_listing = []
		
		for filter_item in RECENT_ITEM_FILTERS:
			this_list = dict()
			this_list['title'] = filter_item[2]
			this_list['rend_id'] = filter_item[3]
			this_list['extra_fields'] = filter_item[4]
			this_list['section_header'] = filter_item[5] and filter_item[2]
			#get all items for current type
			method, ident = filter_item[1].split(':')
			extra_fields = filter_item[4]
			meta_type = filter_item[0]
			if method == 'SKIP':
				this_list['items'] = []
			elif method == "HERE":
				this_list['items'] = \
				self.getSiblingsOfType(meta_type, current_object, 
				extra_fields)
			elif method == 'LOOKUP':
				this_list['items'] = \
				self.getSiblingsFromLocation(meta_type, ident, 
				ITEMS_RECENT, extra_fields)
			elif method == 'DSPACE_FEED':
				this_list['items'] = self.getRSSFeedItems(REPOSITORY_FEED_URL)
			else:
				this_list['items'] = []
			item_listing.append(this_list)
		return item_listing

	def getRSSFeedItems(self, feed_url):
		from plonetheme.apkntheme.utils.tools import get_host_url
		current_object = aq_inner(self.context)
		country_name = current_object.Title()
		context_id = current_object.getId()
		feed_url = feed_url.replace("@@CONTEXT_TITLE", country_name)
		feed_url = feed_url.replace("@@CONTEXT_ID", context_id)
		host_url = get_host_url(self.request)
		final_feed_url = host_url + feed_url
		feed_items = getRSSItems(final_feed_url)
		
		feed_items_data = [] 
		if feed_items:
			for entry in feed_items:
				try:
					feed_link = re.findall(u'handle/.*', entry.link)[0]
				except:
					logger.info("Failed to extract handle from rss entry : %s", entry.link)
					feed_link = u''
				feed_item_url = REPOSITORY_URL_ROOT + feed_link
				feed_data = (entry.title, feed_item_url, 
				{u'publishDate': entry.updated})
				feed_items_data.append(feed_data)
		return feed_items_data

	def getFeedData(self):
		feed_data = {}
		current_object = aq_inner(self.context)
		try:
			country_code = getattr(current_object, u'meta_country_code')
		except AttributeError:
			country_code = u''
		lang_code = u'en'
		country_name = current_object.Title()
		rss_url = ANM_FEED_URL %(country_name, lang_code)
		if hasattr(current_object, u'meta_feed_source'):
			rss_url = getattr(current_object, u'meta_feed_source') \
			%(country_code, lang_code)
		
		feed_title = _("apkn_rss_feed_title_country_folders",
		default = "${country_name} News Feed - ANM",
		mapping = {u'country_name': country_name})
		
		feed_data['feed_url'] = rss_url
		feed_data['feed_title'] = feed_title
		feed_data['dom_id'] = random_string()
		feed_data['news_url'] = self.getNewsURL()
		return feed_data

	@ram.cache(compute_request_cache_key)
	def getFeedItems(self):
		'''
		get a list of dictionaries of feed items
		with keys: title, link
		'''
		logger.info("DASHBOARD: Getting Feed Items. \
		This should be cached for a period of time")
		items = []
		current_object = aq_inner(self.context)
		try:
			country_code = getattr(current_object, u'meta_country_code')
		except AttributeError:
			country_code = u''
		lang_code = u'en'
		country_name = current_object.Title()
		
		rss_url = ANM_FEED_URL %(country_name, lang_code)
		if hasattr(current_object, u'meta_feed_source'):
			rss_url = getattr(current_object, u'meta_feed_source') \
			%(country_code, lang_code)
			
		try:
			feed_content = pq(rss_url)
			feed_items = pq('item', pq(feed_content))
			for item in feed_items:
				link = pq('link', pq(item))
				title = pq('title', pq(item))
				link_text = pq(link).text()
				title_text = pq(title).text()
				items.append({'title':title_text,'link': link_text})
				if len(items) > RECENT_ITEM_COUNT:
					break
		except Exception, e:
			logger.error("Failed to load news Feed for country %s.\
			 Error @@  %s", country_name, e.__str__())
		return items

	def getNewsURL(self):
		current_object = aq_inner(self.context)
		try:
			country_code = getattr(current_object, u'meta_country_code')
		except AttributeError:
			country_code = u''
		lang_code = u'en'
		news_url = ANM_NEWS_URL %(lang_code, country_code.upper())
		return news_url

class countryFolderRoot(BrowserView):
	'''
	Render Content for all countries
	filtered by type
	'''
	def getSiblings(self):
		all_ids = self.context.objectIds()
		folders = []
		for oid in all_ids:
			obj = getattr(self.context, oid)
			if obj.meta_type == u'ATFolder' and obj.Title() != '':
				folders.append(obj)
		contentMap = []
		for folder in folders:
			folder_id = folder.getId()
			folder_url = folder.absolute_url()
			folder_title = folder.Title()
			flag = self.getCountryFlag(folder)
			children = self.getContextLinkItem(folder)
			this_map = (folder_title, folder_url, children, flag)
			contentMap.append(this_map)
		return contentMap

	def getSiblingsOfType(self, meta_type, container):
		item_list = []
		object_ids = container.objectIds()
		for oid in object_ids:
			obj = getattr(container, oid)
			if obj.portal_type in meta_type:
				title = obj.Title()
				link = obj.absolute_url()
				item_list.append((title, link))
			if len(item_list) >= RECENT_ITEM_COUNT:
				break
		return item_list



	def getContextLinkItem(self, folder):
		'''
		Gets the menu items for country the current country folder
		See: COUNTRY_CONTEXT_MENU defined at the top of this module
		'''
		CONTEXT_ID = folder.id
		CONTEXT_TITLE = folder.Title()
		url_action = self.validateParam(PARAM_CONTENT_FILTER,
		ALLOWED_DASHBOARD_ACTIONS)
		context_link_data = None
		if url_action:
			cmenu = filter(lambda x: x[4] == url_action, 
						COUNTRY_CONTEXT_MENU)[0]
			link = cmenu[1]
			link = link.replace(u'@@CONTEXT_ID', CONTEXT_ID)
			link = link.replace(u'@@CONTEXT_TITLE', CONTEXT_TITLE)
			
			if cmenu[2]:
				content_items = self.getSiblingsOfType(cmenu[2], 
				folder)
				if len(content_items) == 1:
					link = content_items[0][1]
				else:
					link = None
			
			show = cmenu[3]
			if (not show) and (self.isUserAnonymous()):
				pass
			else:
				context_link_data = {'title': cmenu[0], 'link': link}
		return context_link_data


	def filterTypes(self, parent):
		matched_objects = []
		url_action = self.validateParam(PARAM_CONTENT_FILTER,
		ALLOWED_DASHBOARD_ACTIONS)
		if url_action:
			filter_type = TYPE_FILTERS[url_action]
			oids = parent.objectIds()
			for id in oids:
				obj = getattr(parent, id)
				if obj.portal_type == filter_type:
					ob_data = {}
					if obj.Title() in REPLACE_TITLE:
						ob_data[u'title'] = aq_parent(obj).Title()
					else:
						ob_data[u'title'] = obj.Title()
					ob_data[u'url'] = obj.absolute_url()
					matched_objects.append(ob_data)
		return matched_objects

	def getRequestParam(self, paramName):
		param = self.request.form.get(paramName,None)
		return param
		
	def validateParam(self, paramName, filterValues):
		param = self.getRequestParam(paramName)
		if param in filterValues:
			return param
		else:
			return None

	def getCountryFlag(self, folder):
		country_name = unicode(folder.Title())
		lang_tool = getToolByName(self.context, u'portal_languages', None)
		countries = lang_tool.getAvailableCountries()
		this_country = filter(lambda x: x[u'name'] == country_name, countries.values())
		if this_country:
			return this_country[0][u'flag']
		else:
			return None

	def getDashboardSectionTitle(self):
		type_filter = self.getRequestParam(PARAM_CONTENT_FILTER)
		context_title = SECTION_TITLES[type_filter]
		return context_title



class FolderTreeStrategy(NavtreeStrategyBase):
	'''
	Navigation strategy for generated folder tree
	'''
	def decoratorFactory(self, node):
		#hack to exclude Profiles Folders from Navigation
		node['purge_from_nav'] = False
		if unicode(node['item'].Title, errors='replace') == u'Profiles':
			node['purge_from_nav'] = True
		return node
	
class BrowseParliamentaryProfiles(BrowserView):
	'''
	Renders search form and a hierarchical directory listing
	of parliametary profiles
	'''
	def buildSearchQuery(self):
		search_query = {}
		search_query['path'] = self.getSearchPath()
		search_query['Type'] = self.getSearchTypes()
		return search_query

	def searchSubmitted(self):
		return self.request.form.get(SEARCH_BUTTON_PARAM, None)

	@memoize
	def searchResults(self):
		'''
		This returns a folder tree of the search results for easier
		browsing. The structure of the search query can be extended
		to customize the results through sorts, limits e.t.c
		Look at Products.ZCatalog for details
		'''
		search_query = self.buildSearchQuery()
		strategy = FolderTreeStrategy()
		return buildFolderTree(self.context, 
								query=search_query, 
								strategy = strategy)

	def getSearchTypes(self):
		'''
		override this to search other object types
		'''
		return PARLIAMENTARY_PROFILES_TYPES

	def getSearchPath(self):
		'''
		Override this method to use a different strategy to generate the
		search path. This assumes that the view's container is the 
		search path we are interested in.
		'''
		search_path = ''
		current_object = aq_inner(self.context)
		if current_object:
			search_path = '/'.join(current_object.getPhysicalPath())
		else:
			portal_tool = self.context.portal_url
			portal_object = portal_tool.getPortalObject()
			search_path = '/'.join(portal_object.getPhysicalPath())
		return search_path


class BrowseParliamentaryContacts(BrowseParliamentaryProfiles):
	'''
	Returns a folder tree of contacts for each or all countries
	'''
	def getSearchTypes(self):
		return COUNTRY_CONTACTS_TYPES
